#include "LecteurPhraseAvecArbre.h"

#include <stdlib.h>
#include <iostream>
using namespace std;

////////////////////////////////////////////////////////////////////////////////

LecteurPhraseAvecArbre::LecteurPhraseAvecArbre(string nomFich)
    : LecteurPhraseAbstrait() {
    ls = new LecteurSymbole(nomFich);
}

////////////////////////////////////////////////////////////////////////////////

void LecteurPhraseAvecArbre::genCode() {
    fstream f("main_genere.cpp", ios_base::trunc | ios_base::out);

    if (f.fail()) {
        cout << "\n\nImpossible d'ouvrir ou de créer le fichier main_genere.cpp\n\n";
        return;
    }
    f << "\n\n#include <iostream>\n\nusing namespace std;\n\n";
    // declarations des fonctions
    for (unsigned i=0; i<tf.size(); i++)
        ((LecteurFonction*)tf[i])->genCode(f);
    // fonction main :
    f << "int main(void)\n{\n";
    // code des variables
    for (unsigned i=0; i<ts.size(); i++){
        if (ts[i]=="<VARIABLE>"){
            f << "    int ";
            ts[i].genCode(f, 0);
            f << ";\n";
        }
    }
    // code du main
    arbre->genCode(f, 1);
    f << "\n    return 0;\n}\n\n";

    cout << "\n\nLe fichier main_genere.cpp a été généré à partir du code kiwi\n\n"
         << "===================================================================\n"
         << "== compilation de main_genere.cpp =================================\n";
    f.close();
    system("g++ ./main_genere.cpp -o programme_genere");
    cout << "===================================================================\n";
}

////////////////////////////////////////////////////////////////////////////////

Noeud* LecteurPhraseAvecArbre::programme() {
    // <programme> ::= debut <seq_inst> fin FIN_FICHIER
    seqFonc();
    sauterSymCour("debut");
    Noeud* si = seqInst();
    sauterSymCour("fin");
    testerSymCour("<FINDEFICHIER>");
    return si;
}

// <seqInst> ::= { <fonction> }
 void LecteurPhraseAvecArbre::seqFonc(){
    // Les fonctions sont créées et lues dans le fichier :
    while (ls->getSymCour()=="fonction"){
        LecteurFonction *lf = new LecteurFonction(ls, tf);
        // Le main a accès à la fonction :
        ajFonction(lf);
    }
 }
